package com.liuym.classes.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.liuym.classes.common.LogAndExceptionCommon;
import com.liuym.classes.repository.mapper.ClassesMapper;
import com.liuym.classes.repository.model.bo.ClassBO;
import com.liuym.classes.repository.model.bo.ClassScoreBatchBO;
import com.liuym.classes.repository.model.entity.Classes;
import com.liuym.classes.service.ClassScoreService;
import com.liuym.classes.service.ClassService;
import com.liuym.common.constants.Constants;
import com.liuym.common.constants.ResponseCodeConstants;
import com.liuym.common.dubbo.classes.dto.ClassDTO;
import com.liuym.common.dubbo.student.api.StudentDubboService;
import com.liuym.common.dubbo.student.api.StudentScoreDubboService;
import com.liuym.common.dubbo.student.dto.StudentDTO;
import com.liuym.common.dubbo.table.api.TableNameDubboService;
import com.liuym.common.dubbo.table.dto.TableNameDTO;
import com.liuym.common.exception.ClassException;
import com.liuym.common.exception.StudentException;
import com.vip.vjtools.vjkit.mapper.BeanMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author LiuYiMing
 * @date 2018/10/25 17:22
 * @describe：
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ClassServiceImpl implements ClassService {

    private static Logger logger = LoggerFactory.getLogger(ClassServiceImpl.class);

    @Autowired
    private ClassesMapper classesMapper;

    @Autowired
    private ClassScoreService classScoreService;

    @Reference(version = "${student.dubbo.version}")
    private StudentDubboService studentDubboService;

    @Reference(version = "${student.dubbo.version}")
    private StudentScoreDubboService studentScoreDubboService;

    @Reference(version = "${admin.dubbo.version}")
    private TableNameDubboService tableNameDubboService;

    @Override
    public List<ClassBO> getAllClass() throws ClassException {
        List<Classes> classesList = classesMapper.getAllClass();
        if (classesList.size() > 0 && classesList != null) {
            List<ClassBO> classBOList =
                    classesList
                            .stream()
                            .map(s -> BeanMapper.map(s, ClassBO.class))
                            .collect(Collectors.toList());

            return classBOList;
        }
        return null;
    }

    @Override
    public ClassBO getClassByNumber(long classNumber) throws ClassException {
        Classes classes = classesMapper.getClassByNumber(classNumber);
        if (classes != null) {
            return BeanMapper.map(classes, ClassBO.class);
        }
        return null;
    }

    @Override
    public List<Integer> getAllYear() throws ClassException {
        return classesMapper.getAllYear();
    }

    @Override
    public int deleteClass(long classNumber) throws ClassException {
        int i = 0;
        classesMapper.deleteClass(classNumber);
        try {
            //删除班级分数
            TableNameDTO classTable = tableNameDubboService.findByTableAndTime(Constants.CLASS_SCORE_TABLE_NAME);
            classScoreService.deleteClassScoreByNumber(classTable.getTableName(), classNumber);
            //删除学生分数
            TableNameDTO studentTable = tableNameDubboService.findByTableAndTime(Constants.STUDENT_SCORE_TABLE_NAME);
            List<StudentDTO> studentDTOList = studentDubboService.getStudentByClass(classNumber);
            if (studentDTOList != null && studentDTOList.size() > 0) {
                for (StudentDTO studentDTO : studentDTOList) {
                    studentScoreDubboService.deleteStudentScoreByNumber(studentTable.getTableName(), studentDTO.getStudentNumber());
                }
            }
            //删除学生
            logger.info("开始调用 studentDubboService.deleteStudentByClassNumber，param:{}", classNumber);
            i = studentDubboService.deleteStudentByClassNumber(classNumber);
            logger.info("调用 studentDubboService.deleteStudentByClassNumber结束，result:{}", i);


        } catch (Exception e) {
            logger.error("删除班级失败！", e);
            throw ClassException.internalServerError();
        }
        return i;
    }

    @Override
    public int updateClass(ClassBO classBO) throws ClassException {
        baseParamCheck(classBO);
        Classes classes = BeanMapper.map(classBO, Classes.class);
        return classesMapper.updateByPrimaryKeySelective(classes);
    }

    @Override
    public int addClass(ClassBO classBO) throws ClassException {
        if (null != getClassByNumber(classBO.getClassNumber())) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.CLASSNUMBER_IS_EXIST_CODE,
                    ResponseCodeConstants.CLASSNUMBER_IS_EXIST_MSG,
                    "");
        }
        baseParamCheck(classBO);
        classBO.setScore(80);
        Classes classes = BeanMapper.map(classBO, Classes.class);
        return classesMapper.insert(classes);
    }

    @Override
    public Map<String, Object> addClassList(List<ClassBO> classBOList) throws ClassException {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Classes> classesList = new ArrayList<Classes>();
        List failList = new ArrayList(); //存脏数据数据
        int failResult = 0;
        List<Long> classNumberList = classesMapper.findClassNumberList();
        for (ClassBO classBO : classBOList) {

            String checkExcelParam = checkExcelParam(classBO, classNumberList);

            if ("验证通过!".equals(checkExcelParam)) {
                classBO.setScore(80);
                Classes classes = BeanMapper.map(classBO, Classes.class);
                classesList.add(classes);
            } else {
                failResult++;
                failList.add(BeanMapper.map(classBO, ClassDTO.class));
                failList.add(checkExcelParam);
            }
        }
        map.put("failResult", failResult);
        map.put("failReason", failList);
        classesMapper.addClassList(classesList);
        return map;
    }

    @Override
    public int updateScoreByClassNumber(int score, long classNumber) throws ClassException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("score", score);
        map.put("classNumber", classNumber);
        return classesMapper.updateScoreByClassNumber(map);
    }

    @Override
    public int updateScoreByClassNumberBatch(List<ClassScoreBatchBO> classScoreBatchBOList) throws ClassException {
        return classesMapper.updateScoreByClassNumberBatch(classScoreBatchBOList);
    }

    @Override
    public int updateClassScoreTo80() throws ClassException {
        return classesMapper.updateClassScoreTo80();
    }

    private String checkExcelParam(ClassBO classBO, List<Long> classNumberList) {
        if (null == classBO.getClassNumber() || "".equals(classBO.getClassNumber())) {
            return "班级号码不能为空！";
        }
        if (null == classBO.getClassName() || "".equals(classBO.getClassName())) {
            return "学生姓名不能为空！";
        }
        if (null == classBO.getMajorName() || "".equals(classBO.getMajorName())) {
            return "专业不能为空！";
        }
        if (null == classBO.getYear() || "".equals(classBO.getYear())) {
            return "年级不能为空！";
        }
        if (null == classBO.getMonitor() || "".equals(classBO.getMonitor())) {
            return "班长不能为空！";
        }
        if (classNumberList.contains(classBO.getClassNumber())) {
            return "班号号不能重复！";
        }
        return "验证通过!";
    }

    /**
     * 检查参数
     *
     * @param classBO
     * @return
     * @throws StudentException
     */
    private void baseParamCheck(ClassBO classBO) throws ClassException {

        if (null == classBO.getClassName()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.CLASSNAME_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.CLASSNAME_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == classBO.getClassNumber()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.CLASSNUMBER_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.CLASSNUMBER_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == classBO.getMajorName()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.MAJORNAME_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.MAJORNAME_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == classBO.getMonitor()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.MONITOR_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.MONITOR_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == classBO.getYear()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.YEAR_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.YEAR_IS_NOT_NULL_MSG,
                    "");
        }
    }

}
